package com.leyou.gateway.filter;

import com.leyou.common.auth.pojo.Payload;
import com.leyou.common.auth.pojo.UserInfo;
import com.leyou.common.auth.utils.JwtUtils;
import com.leyou.common.constants.LyConstants;
import com.leyou.gateway.config.FilterProperties;
import com.leyou.gateway.config.JwtProperties;
import com.leyou.gateway.auth.schedu.AppTokenScheduled;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * User: ycs
 * Date: 2020/8/31
 * Time: 16:03
 *
 * @author: ycs
 * Description: 自定义过滤器
 */
@Component
public class AuthFilter implements GlobalFilter, Ordered {
    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private FilterProperties filterProperties;
    @Autowired
    private AppTokenScheduled appTokenScheduled;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //获取request
        ServerHttpRequest request = exchange.getRequest();
        //response
        ServerHttpResponse response = exchange.getResponse();
        //设置请求头携带token
        request.mutate().header(LyConstants.APP_TOKEN_HEADER,appTokenScheduled.getToken()).build();
        //获取请求地址
        String uri = request.getPath().toString();
        //白名单直接放行
        if (requestAuthentication(uri)){
            //放行
            return chain.filter(exchange);
        }
        //获取token
        String token;
        Payload<UserInfo> payload;
        try {
            token = request.getCookies().getFirst(jwtProperties.getCookie().getCookieName()).getValue();
            //解析token
             payload= JwtUtils.getInfoFromToken(token, jwtProperties.getPublicKey(), UserInfo.class);
        } catch (Exception e) {
            e.printStackTrace();
            //未经授权
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            //阻断
            return response.setComplete();
        }
        //获取当前用户
        UserInfo userInfo = payload.getUserInfo();
        //放行
        return chain.filter(exchange);
    }

    /**
     * 鉴定是否白名单(不登录可访问)
     * @param uri
     * @return
     */
    private boolean requestAuthentication(String uri) {
        //获取白名单集合
        List<String> allowPaths = filterProperties.getAllowPaths();
        for (String allowPath : allowPaths) {
            //白名单
            if (uri.contains(allowPath)){
                return true;
            }
        }
        return false;
    }

    /**
     * Get the order value of this object.
     * <p>Higher values are interpreted as lower priority. As a consequence,
     * the object with the lowest value has the highest priority (somewhat
     * analogous to Servlet {@code load-on-startup} values).
     * <p>Same order values will result in arbitrary sort positions for the
     * affected objects.
     *
     * @return the order value
     * @see #HIGHEST_PRECEDENCE
     * @see #LOWEST_PRECEDENCE
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
